package org.resotc.model;

import java.util.HashMap;
import java.util.List;

import sim.util.Double2D;

public interface Element {
	
	/**
	 * Returns the position of an element as Double2D.
	 * @return
	 */
	public abstract Double2D getPosition();
	
	/**
	 * Sets the x-coordinate of an element.
	 * @param x
	 */
	public abstract void setX(double x);
	
	/**
	 * Sets the y-coordinate of an element.
	 * @param y
	 */
	public abstract void setY(double y);

	/**
	 * Returns the x-coordinate of an element.
	 * @return
	 */
	public abstract double getX();
	
	/**
	 * Returns the y-coordinate of an element.
	 * @return
	 */
	public abstract double getY();
	
	/**
	 * Returns the correct instance of the current element.
	 * @return
	 */
	public abstract ElementType getElementType();
	
	/**
	 * Sets the type of the element.
	 * @param e
	 */
	public abstract void setElementType(ElementType type);
	
	/**
	 * Returns the id of an element.
	 * @return
	 */
	public abstract int getId();

	public abstract void addArrivingIndividual(Individual newInd, NeighbourOrientation n);

	public abstract void modifyCapacity(double decreaseRate);

	public abstract void setInitialCapacity(double cap);

	public abstract int getNumberOfIndividuals();

	public abstract double getEstimatedLength();
	
	public abstract double getCapacity();

	public abstract double getLength();

	public abstract void setLength(double length);

	public abstract boolean isElementCrowded(NeighbourOrientation or);

	public abstract void setElementCrowded(boolean isElementCrowded, NeighbourOrientation or);

	public abstract double estimateDensity();

	/**
	 * Returns a HashMap of all neighbours with their relative orientation to
	 * the
	 * 
	 * @param node
	 * @return
	 */
	public abstract HashMap<NeighbourOrientation, Element> determineNeighbours();

	public abstract boolean isNeighbour(Element neighbour);

	public abstract HashMap<NeighbourOrientation, Element> getNeighbours();

	public abstract HashMap<NeighbourOrientation, Element> getDestinations();

	public abstract void addElement(Element element);

	public abstract List<Element> getElements();

	/**
	 * Returns the correct instance of a element, whether it is a intersection
	 * or a centroid.
	 * 
	 * @param element
	 * @return
	 */
	public abstract Element getElement(Element element);
	
	/**
	 * Returns all streets which are connected to a centroid or a intersection.
	 * @return
	 */
	public abstract HashMap<NeighbourOrientation, Street> getConnectedStreets(); 
	
	/**
	 * Returns the containing quadrant of a neighbour.
	 * @param predecessor
	 * @param successor
	 */
	public abstract int determineQuadrant(Element predecessor, Element successor);
	
	public List<Double2D> getConnections(Element src, Element dst, Street street, int quadrant);
	
}